package com.blacktech.dbu.meta.service;

import com.blacktech.dbu.meta.dto.CreateColumnFromLibraryRequest;
import com.blacktech.dbu.meta.entity.DbuColumn;
import com.blacktech.dbu.meta.entity.DbuFieldLibrary;
import com.blacktech.dbu.meta.entity.DbuTable;
import com.blacktech.dbu.meta.repository.ColumnRepository;
import com.blacktech.dbu.meta.repository.FieldLibraryRepository;
import com.blacktech.dbu.meta.repository.TableRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 表字段管理服务类
 * 支持从字段库选择字段创建表字段
 *
 * @author Yanyunsong
 */
@Slf4j
@Service
@Transactional
public class ColumnService {

    @Autowired
    private ColumnRepository columnRepository;

    @Autowired
    private TableRepository tableRepository;

    @Autowired
    private FieldLibraryRepository fieldLibraryRepository;

    /**
     * 从字段库创建表字段
     */
    public DbuColumn createColumnFromLibrary(CreateColumnFromLibraryRequest request) {
        log.info("从字段库创建表字段: tableId={}, fieldLibraryId={}",
                request.getTableId(), request.getFieldLibraryId());

        // 验证表是否存在
        Optional<DbuTable> optionalTable = tableRepository.findById(request.getTableId());
        if (!optionalTable.isPresent()) {
            throw new RuntimeException("数据表不存在: " + request.getTableId());
        }
        DbuTable table = optionalTable.get();

        // 验证字段库是否存在
        Long fieldLibraryId = request.getFieldLibraryId();
        DbuFieldLibrary fieldLibrary = fieldLibraryRepository.findById(fieldLibraryId).orElseThrow(() -> new RuntimeException("字段库记录不存在: " + fieldLibraryId));

        // 验证字段库与表的产品是否匹配
        if (!fieldLibrary.getProductId().equals(table.getSchema().getProduct().getId())) {
            throw new RuntimeException("字段库与表不属于同一产品");
        }

        // 检查表中是否已存在同名字段
        if (columnRepository.existsByTableIdAndColumnName(request.getTableId(), fieldLibrary.getFieldNameEn())) {
            throw new RuntimeException("表中已存在字段: " + fieldLibrary.getFieldNameEn());
        }

        // 创建字段
        DbuColumn column = new DbuColumn();
        column.setColumnName(fieldLibrary.getFieldNameEn());
        column.setColumnComment(request.getColumnComment() != null ?
                request.getColumnComment() : fieldLibrary.getFieldComment());
        column.setColumnType(fieldLibrary.getFieldType());
        column.setColumnLength(fieldLibrary.getFieldLength());
        column.setColumnPrecision(fieldLibrary.getFieldLength());
        column.setColumnScale(fieldLibrary.getFieldScale());
        column.setDefaultValue(request.getDefaultValue() != null ?
                request.getDefaultValue() : fieldLibrary.getDefaultValue());
        column.setIsRequired(fieldLibrary.getIsRequired());
        column.setIsPrimaryKey(request.getIsPrimaryKey() != null ?
                request.getIsPrimaryKey() : fieldLibrary.getIsPrimaryKey());
        column.setIsUnique(request.getIsUnique() != null ?
                request.getIsUnique() : fieldLibrary.getIsUnique());
        column.setSortOrder(request.getSortOrder());
        column.setFromFieldLibrary(true);
        column.setFieldLibraryId(fieldLibrary.getId());
        column.setTable(table);

        // 保存字段
        DbuColumn savedColumn = columnRepository.save(column);

        // 增加字段库使用次数
        fieldLibraryRepository.incrementUsageCount(fieldLibrary.getId());

        return savedColumn;
    }

    /**
     * 创建自定义字段（不从字段库选择）
     */
    public DbuColumn createCustomColumn(DbuColumn column) {
        log.info("创建自定义字段: columnName={}, tableId={}",
                column.getColumnName(), column.getTable().getId());

        // 验证表是否存在
        if (column.getTable() == null || column.getTable().getId() == null) {
            throw new RuntimeException("表ID不能为空");
        }

        Optional<DbuTable> optionalTable = tableRepository.findById(column.getTable().getId());
        if (!optionalTable.isPresent()) {
            throw new RuntimeException("数据表不存在: " + column.getTable().getId());
        }

        // 检查表中是否已存在同名字段
        if (columnRepository.existsByTableIdAndColumnName(column.getTable().getId(), column.getColumnName())) {
            throw new RuntimeException("表中已存在字段: " + column.getColumnName());
        }

        column.setFromFieldLibrary(false);
        column.setFieldLibraryId(null);
        column.setTable(optionalTable.get());

        return columnRepository.save(column);
    }

    /**
     * 更新字段信息
     */
    public DbuColumn updateColumn(Long id, DbuColumn columnUpdate) {
        log.info("更新字段信息: {}", id);

        Optional<DbuColumn> optionalColumn = columnRepository.findById(id);
        if (!optionalColumn.isPresent()) {
            throw new RuntimeException("字段不存在: " + id);
        }

        DbuColumn column = optionalColumn.get();

        // 如果是从字段库创建的字段，限制可修改的字段
        if (Boolean.TRUE.equals(column.getFromFieldLibrary())) {
            // 只允许修改部分字段
            if (columnUpdate.getIsPrimaryKey() != null) {
                column.setIsPrimaryKey(columnUpdate.getIsPrimaryKey());
            }
            if (columnUpdate.getIsUnique() != null) {
                column.setIsUnique(columnUpdate.getIsUnique());
            }
            if (columnUpdate.getDefaultValue() != null) {
                column.setDefaultValue(columnUpdate.getDefaultValue());
            }
            if (columnUpdate.getColumnComment() != null) {
                column.setColumnComment(columnUpdate.getColumnComment());
            }
            if (columnUpdate.getSortOrder() != null) {
                column.setSortOrder(columnUpdate.getSortOrder());
            }
        } else {
            // 自定义字段可以修改所有属性
            if (columnUpdate.getColumnName() != null) {
                column.setColumnName(columnUpdate.getColumnName());
            }
            if (columnUpdate.getColumnComment() != null) {
                column.setColumnComment(columnUpdate.getColumnComment());
            }
            if (columnUpdate.getColumnType() != null) {
                column.setColumnType(columnUpdate.getColumnType());
            }
            if (columnUpdate.getColumnLength() != null) {
                column.setColumnLength(columnUpdate.getColumnLength());
            }
            if (columnUpdate.getColumnPrecision() != null) {
                column.setColumnPrecision(columnUpdate.getColumnPrecision());
            }
            if (columnUpdate.getColumnScale() != null) {
                column.setColumnScale(columnUpdate.getColumnScale());
            }
            if (columnUpdate.getDefaultValue() != null) {
                column.setDefaultValue(columnUpdate.getDefaultValue());
            }
            if (columnUpdate.getIsRequired() != null) {
                column.setIsRequired(columnUpdate.getIsRequired());
            }
            if (columnUpdate.getIsPrimaryKey() != null) {
                column.setIsPrimaryKey(columnUpdate.getIsPrimaryKey());
            }
            if (columnUpdate.getIsUnique() != null) {
                column.setIsUnique(columnUpdate.getIsUnique());
            }
            if (columnUpdate.getSortOrder() != null) {
                column.setSortOrder(columnUpdate.getSortOrder());
            }
        }

        return columnRepository.save(column);
    }

    /**
     * 删除字段
     */
    public void deleteColumn(Long id) {
        log.info("删除字段: {}", id);

        if (!columnRepository.existsById(id)) {
            throw new RuntimeException("字段不存在: " + id);
        }

        columnRepository.deleteById(id);
    }

    /**
     * 根据ID获取字段
     */
    @Transactional(readOnly = true)
    public DbuColumn getColumnById(Long id) {
        return columnRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("字段不存在: " + id));
    }

    /**
     * 根据表ID获取字段列表
     */
    @Transactional(readOnly = true)
    public List<DbuColumn> getColumnsByTableId(Long tableId) {
        return columnRepository.findByTableIdOrderBySortOrder(tableId);
    }

    /**
     * 批量从字段库创建字段
     */
    public List<DbuColumn> batchCreateColumnsFromLibrary(Long tableId, List<Long> fieldLibraryIds) {
        log.info("批量从字段库创建字段: tableId={}, count={}", tableId, fieldLibraryIds.size());

        // 验证表是否存在
        Optional<DbuTable> optionalTable = tableRepository.findById(tableId);
        if (!optionalTable.isPresent()) {
            throw new RuntimeException("数据表不存在: " + tableId);
        }

        return fieldLibraryIds.stream()
                .map(fieldLibraryId -> {
                    CreateColumnFromLibraryRequest request = new CreateColumnFromLibraryRequest();
                    request.setTableId(tableId);
                    request.setFieldLibraryId(fieldLibraryId);
                    return createColumnFromLibrary(request);
                })
                .toList();
    }

    /**
     * 检查字段名是否在表中已存在
     */
    @Transactional(readOnly = true)
    public boolean existsColumnNameInTable(Long tableId, String columnName) {
        return columnRepository.existsByTableIdAndColumnName(tableId, columnName);
    }
}